package com.fuyun.rpc.server.protocol;

import com.fuyun.rpc.common.serializer.Serializer;
import com.fuyun.rpc.server.config.RpcConfig;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.WorkerExecutor;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetSocket;
import lombok.extern.slf4j.Slf4j;

/**
 * @author: zrq1351
 * @date: 2025/2/20
 */
@Slf4j
public class VertxTcpServerHandler extends AbstractServerHandler implements Handler<NetSocket> {

	private final WorkerExecutor workerExecutor;
	private final Vertx vertx = Vertx.vertx();

	public VertxTcpServerHandler(Serializer serializer, RpcConfig rpcConfig) {
		super(serializer, rpcConfig);

		int poolSize = Math.min(rpcConfig.getWorkerPoolSize() > 0 ? rpcConfig.getWorkerPoolSize() : 10, 200);
		long maxExecuteTime =
			Math.max(rpcConfig.getMaxWorkerExecutionTime() > 0 ? rpcConfig.getMaxWorkerExecutionTime() : 120000L,
				30000L);

		// 使用共享的 WorkerExecutor
		this.workerExecutor = vertx.createSharedWorkerExecutor("tcp-worker-pool", poolSize, maxExecuteTime);
	}

	/**
	 * 关闭 NetSocket 的安全方法
	 *
	 * @param socket NetSocket 对象
	 */
	private static void closeSocketSafely(NetSocket socket) {
		if (socket != null) {
			try {
				socket.close();
			} catch (Exception e) {
				log.warn("Error closing socket: {}", e.getMessage());
			}
		}
	}

	@Override
	public void handle(NetSocket socket) {
		socket.handler(buffer -> {
			workerExecutor.executeBlocking(() -> {
					processData(buffer, new TcpServerConnection(socket));
					return null;
				})
				.onFailure(throwable -> log.error("处理TCP请求时发生错误", throwable));
		});
	}

	/**
	 * 发送响应数据的方法 该方法负责将响应数据发送给客户端
	 *
	 * @param connection    服务器连接对象，用于发送数据
	 * @param responseBuffer 包含响应数据的缓冲区
	 */
	@Override
	protected void sendResponse(ServerConnection connection, Buffer responseBuffer) {
		if (connection instanceof TcpServerConnection) {
			((TcpServerConnection)connection).sendResponse(responseBuffer);
		}
	}

	/**
	 * 发送错误响应的方法 该方法用于向客户端发送错误信息
	 *
	 * @param connection 服务器连接对象，用于发送数据
	 * @param message    错误消息
	 */
	@Override
	protected void sendErrorResponse(ServerConnection connection, String message) {
		if (connection instanceof TcpServerConnection) {
			((TcpServerConnection)connection).sendErrorResponse(message);
		}
	}

	/**
	 * TCP服务器连接实现类 该类实现了ServerConnection接口，用于处理TCP连接的相关操作
	 */
	private static class TcpServerConnection implements ServerConnection {
		private final NetSocket socket;

		public TcpServerConnection(NetSocket socket) {
			this.socket = socket;
		}

		/**
		 * 发送响应数据的方法 该方法用于向客户端发送响应数据 它首先记录响应数据的长度，然后使用TCP套接字发送响应数据
		 *
		 * @param buffer 包含响应数据的缓冲区
		 */
		public void sendResponse(Buffer buffer) {
			log.info("响应正文长度: {}", buffer.length());
			socket.write(buffer);
		}

		/**
		 * 发送错误响应的方法 该方法用于向客户端发送错误响应 它将错误消息作为字节数据发送给客户端
		 *
		 * @param message 错误消息
		 */
		public void sendErrorResponse(String message) {
			log.error("发送错误响应: {}", message);
			socket.write(Buffer.buffer(message.getBytes()));
		}

		@Override
		public void close() {
			closeSocketSafely(socket);
		}
	}
}